package com.winit.openapi.ums.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.SearchOperator;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.filter.SearchFilterHelper;
import com.winit.common.spi.context.CommandContext;
import com.winit.common.utils.JsonMapper;
import com.winit.erp.spi.bpartner.BpartnerService;
import com.winit.erp.spi.bpartner.command.BpartnerCommand;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.openapi.constants.EnumConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.ValidateUtil;
import com.winit.ums.spi.EorIorInfoService;
import com.winit.ums.spi.commnad.AddEorIorInfoCommand;
import com.winit.ums.spi.commnad.EorIorInfoCommand;
import com.winit.ums.spi.commnad.UpdateEorIorInfoCommand;
import com.winit.ums.spi.commnad.queryEorIorInfoCommand;
import com.winit.ums.spi.vo.EorIorInfo;
import com.winit.ums.spi.vo.EorIorInfoDetailVo;
import com.winit.ups.spi.systemrule.CountryService;
import com.winit.ups.spi.systemrule.vo.Country;

/**
 * 进口商/出口商Controller
 * 
 * @author long.chen
 */
@Controller
@RequestMapping(value = "ums/eorIorInfo")
public class EorIorInfoController extends BaseController {

	private Logger  logger = LoggerFactory.getLogger(EorIorInfoController.class);
	
    @Resource
    EorIorInfoService  eorIorInfoService;

    @Resource
    CountryService    countryService;

    @Resource
    BpartnerService   bpartnerService;

    /**
     * 新增进口商/出口商
     * 
     * @param requestMsg
     * @param responseMsg
     * @return String
     */
    @RequestMapping(value = "/addEorIorInfo")
    public String addEorIorInfo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        logger.info("新增进出口商信息开始");
        Object params = requestMsg.getData();
        JSONObject json = null;
        if (params instanceof JSONObject) {
            json = (JSONObject) params;
            validateParams(json);
        } else {
            logger.info("新增进口商/出口商入参格式错误。 ");
			throw new ApiException(ErrorCode.ILLEGAL_JSON_STRING, "addEorIorInfo");
        }
        AddEorIorInfoCommand command = JsonMapper.fromJson(json.toString(), AddEorIorInfoCommand.class);
        command.setCtx(CommandContext.getContext());
        command.setUserId(CommandContext.getContext().getUserId());
        // 根据ID设置用户名，此用户名并非上下文用户名
        String name = getNameById(Long.parseLong(CommandContext.getContext().getUserId()));
        command.setUserName(name);
        
        // 新增进口商/出口商默认状态为:未审核
        command.setStatus(EnumConstant.EorIorStatus.WFC.getVal());
        eorIorInfoService.addEorIorInfo(command);
        logger.info("新增进出口商信息成功");
        return SUCCESS;
    }

    /**
     * 修改进口商/出口商
     * 
     * @param requestMsg
     * @param responseMsg
     * @return String
     */
    @RequestMapping(value = "/updateEorIorInfo")
    public String updateEorIorInfo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        logger.info("修改进出口商信息开始");
        Object params = requestMsg.getData();
        JSONObject json = null;
        if (params instanceof JSONObject) {
            json = (JSONObject) params;
            // id不能为空且长度不超过20
            ValidateUtil.validMaxLength(json, "id", 20, true);

            validateParams(json);
            logger.info("校验通过");
        }else{
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        Long id = json.getLong("id");
        UpdateEorIorInfoCommand command = JsonMapper.fromJson(json.toString(), UpdateEorIorInfoCommand.class);
        command.setCtx(CommandContext.getContext());
        command.setUserId(CommandContext.getContext().getUserId());
        
        // 检查进出口商数据
        EorIorInfoDetailVo detailVo = checkEorIorInfoData(id);

        // 是否存在主要信息变更,则需要重新审批
        if(isValueChange(json, detailVo)){
            logger.info("主要信息变更，设置状态为待审核WFC");
            // 新增进口商/出口商默认状态为:未审核
        	command.setStatus(EnumConstant.EorIorStatus.WFC.getVal());
        }
        // 校验当前修改信息是否是该用户用户的信息
        EorIorInfoCommand getByIdCommand = new EorIorInfoCommand();
        getByIdCommand.setId(id);
        getByIdCommand.setCtx(CommandContext.getContext());
        getByIdCommand.setUserId(CommandContext.getContext().getUserId());
        EorIorInfoDetailVo detail = eorIorInfoService.findEorIorInfoById(getByIdCommand);
        // 校验该记录是否属于当前用户
        String userId = CommandContext.getContext().getUserId();
        if (!userId.equals(detail.getUserId())) {
            logger.info("地址不属于本人，不允许修改" + getByIdCommand);
            throw new ApiException(ErrorCode.RECORD_NOT_BELONG_CURRENT_USER, getByIdCommand.getId());
        }
        eorIorInfoService.updateEorIorInfo(command);
        logger.info("修改进出口商信息成功");
        return SUCCESS;
    }

    /**
     * 删除进口商/出口商
     * 
     * @param requestMsg
     * @param responseMsg
     * @return String
     */
    @RequestMapping(value = "/deleteEorIorInfo")
    public String deleteEorIorInfo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        logger.info("删除进出口商信息");
        Object params = requestMsg.getData();
        JSONObject json = null;
        if (params instanceof JSONObject) {
            json = (JSONObject) params;
            // id不能为空且长度不超过20
            ValidateUtil.validMaxLength(json, "id", 20, true);

        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        Long id = json.getLong("id");

        // 检查进出口商数据
        checkEorIorInfoData(id);

        // 删除进口商/出口商
        EorIorInfoCommand command = new EorIorInfoCommand();
        command.setId(id);
        command.setCtx(CommandContext.getContext());
        command.setUserId(CommandContext.getContext().getUserId());
        EorIorInfoDetailVo detailVo = eorIorInfoService.findEorIorInfoById(command);
        // 校验该记录是否属于当前用户
        String userId = CommandContext.getContext().getUserId();
        if (!userId.equals(detailVo.getUserId())) {
            logger.info("地址不属于本人，不允许修改" + command);
            throw new ApiException(ErrorCode.RECORD_NOT_BELONG_CURRENT_USER, command.getId());
        }

        eorIorInfoService.deleteEorIorInfoById(command);
        logger.info("删除成功");
        return SUCCESS;
    }

    /**
     * 查询进口商/出口商列表，分页
     * 
     * @param requestMsg
     * @param responseMsg
     * @return String
     */
    @SuppressWarnings("rawtypes")
	@RequestMapping(value = "/queryEorIorList")
    public String queryEorIorList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
    	queryEorIorInfoCommand command = new queryEorIorInfoCommand();
        Searchable searchable = Searchable.newSearchable();
        command.setSearchable(searchable);
        searchable.addSort(new Sort(Sort.Direction.DESC, "ID"));
        command.setCtx(CommandContext.getContext());
        command.setUserId(CommandContext.getContext().getUserId());
        Object params = requestMsg.getData();

        JSONObject json = null;
        if (params instanceof JSONObject) {
            json = (JSONObject) params;
            int pageNo = 1, pageSize = 10; // 分页参数
            if (ValidateUtil.isExistValue(json, "pageParams")) {
                JSONObject pageParam = json.getJSONObject("pageParams");
                if (ValidateUtil.isExistValue(pageParam, "pageNo")) {
                    pageNo = pageParam.getIntValue("pageNo") == 0 ? 1 : pageParam.getIntValue("pageNo");

                }
                if (ValidateUtil.isExistValue(pageParam, "pageSize")) {
                    pageSize = pageParam.getIntValue("pageSize");
                }
            }
            searchable.setPage(pageNo - 1, pageSize);
        } else {
            throw new ApiException(ErrorCode.ILLEGAL_JSON_STRING);
        }
        
        // 卖家ID
        searchable.and(SearchFilterHelper.newCondition("user_id", SearchOperator.eq, command.getUserId()));
        Page<EorIorInfo> list = eorIorInfoService.queryEorIorInfoList(command);

        Map<String, Object> data = new HashMap<String, Object>();
        Map<String, Object> page = new HashMap<String, Object>();
        page.put("pageNo", list.getPageable().getPageNumber() + 1);
        page.put("pageSize", list.getPageable().getPageSize());
        page.put("totalCount", list.total);
        data.put("list", list.content);
        data.put("pageParams", page);
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 根据Id获取用户名
     * 
     * @param name
     * @return
     */
    private String getNameById(long id) {
        BpartnerCommand bpartnerCommand = new BpartnerCommand();
        bpartnerCommand.setcBpartnerId(id);
        List<Bpartner> bpartners = bpartnerService.queryBpartner(bpartnerCommand);
        if (bpartners != null && !bpartners.isEmpty()) {
            return bpartners.get(0).getName();
        }
        return "";
    }

    /**
     * 根据id查询进口商/出口商信息
     * 
     * @param requestMsg
     * @param responseMsg
     * @return String
     */
    @RequestMapping(value = "/getEorIorInfo")
    public String getEorIorInfo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
    	Object params = requestMsg.getData();
        JSONObject json = null;
        if (params instanceof JSONObject) {
            json = (JSONObject) params;
            // ID不能为空
            ValidateUtil.validNotNull(json, "id");
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        Long id = json.getLong("id");
        // 查询进口商/出口商
        EorIorInfoCommand command = new EorIorInfoCommand();
        command.setId(id);
        command.setCtx(CommandContext.getContext());
        command.setUserId(CommandContext.getContext().getUserId());
        EorIorInfoDetailVo detailVo = eorIorInfoService.findEorIorInfoById(command);
        responseMsg.setData(detailVo);
        return SUCCESS;
    }
    
    
    /**
     * 根据类型查询进口商/出口商信息列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return String
     */
    @RequestMapping(value = "/queryEorIorInfoByType")
    public String queryEorIorInfoByType(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
    	Object params = requestMsg.getData();
        JSONObject json = null;
        if (params instanceof JSONObject) {
            json = (JSONObject) params;
            // type不能为空
            ValidateUtil.validNotNull(json, "type");
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        String type = json.getString("type");
        String countryCode = json.getString("countryCode");
        String isWinit = json.getString("isWinit");
        // 查询进口商/出口商
        EorIorInfoCommand command = new EorIorInfoCommand();
        command.setCtx(CommandContext.getContext());
        command.setUserId(CommandContext.getContext().getUserId());
        command.setType(type);
        command.setCountryCode(countryCode);
        List<EorIorInfo> list = eorIorInfoService.queryEorIorInfoByType(command);
        if(!StringUtils.isEmpty(isWinit)){
        	List<EorIorInfo> resultList = new ArrayList<EorIorInfo>();
        	for (EorIorInfo eorIorInfo : list) {
        		if(isWinit.equals(eorIorInfo.getIsWinit())){
        			resultList.add(eorIorInfo);
        		}
        	}
        	responseMsg.setData(resultList);
        }else{
			List<EorIorInfo> returnList = new ArrayList<EorIorInfo>();
			for (EorIorInfo eor : list) {
				if ("Y".equals(eor.getIsWinit())) {
					continue;
				}
				returnList.add(eor);
			}
        	responseMsg.setData(returnList);
        }
        return SUCCESS;
    }
    
    /**
     * 校验参数
     * 
     * @param json
     */
    private void validateParams(JSONObject json) {
        // 进出口商类型
        ValidateUtil.validMaxLength(json, "type", 4, true);
        String type = json.getString("type");
        // 判断类型
        if (!EnumConstant.EorIorType.IOR.getVal().equals(type) && !EnumConstant.EorIorType.EOR.getVal().equals(type)) {
            throw new ApiException(ErrorCode.FIELD_INVALID, "type");
        }

//        // 注册国家Code
//        ValidateUtil.validImportMaxLength(json, "registerCountry", "注册国家", 32, true);
//        Country registerCountry = countryService.getCountryByCodeOrName(json.getString("registerCountry"));
//        if (registerCountry == null) {
//            throw new ApiException(ErrorCode.FIELD_INVALID, "注册国家");
//        }

        // 进口商为DE、UK两国才有海关编码
        if (EnumConstant.EorIorType.IOR.getVal().equals(type)) {
            ValidateUtil.validImportMaxLength(json, "eoriNo", "海关编号", 100, true);
        }

        // 经营单位
        ValidateUtil.validImportMaxLength(json, "operationUnit", "经营单位", 256, true);

        // 国家名称
        ValidateUtil.validImportMaxLength(json, "countryName", "国家", 32, true);
        Country country = countryService.getCountryByCodeOrName(json.getString("countryName"));
        if (country == null) {
            throw new ApiException(ErrorCode.FIELD_INVALID, "国家");
        }
        // 州/省
        ValidateUtil.validImportMaxLength(json, "stateName", "州/省", 100, true);
        // 城市
        ValidateUtil.validImportMaxLength(json, "cityName", "城市", 100, true);
        // 邮编(邮编允许为空)
        ValidateUtil.validImportMaxLength(json, "postcode", "邮编", 20, false);
        // 校验是否存在特殊字符
        if (!json.getString("postcode").matches("[^&@#￥$%&(){}<>]{0,}")) {
            throw new ApiException(ErrorCode.NOT_INPUT_SPECHARS, "邮编");
        }

        // 联系人
        ValidateUtil.validImportMaxLength(json, "contactPerson", "联系人", 50, true);
        // 联系电话
        ValidateUtil.validImportMaxLength(json, "contactNumber", "联系电话", 20, true);
        // 邮箱
        ValidateUtil.validEmail(json, "email");
        // 地址1
        ValidateUtil.validImportMaxLength(json, "detail1", "地址1", 500, true);
        // 地址2
        ValidateUtil.validImportMaxLength(json, "detail2", "地址2", 500, false);
        // 门牌号
        ValidateUtil.validImportMaxLength(json, "doorplate", "门牌号", 100, false);
    }
    
    
    /**
     * 数值是否发生变更
     * 
     * @param json
     * @param info
     * @return boolean
     */
    private boolean isValueChange(JSONObject json,EorIorInfoDetailVo info){
        // 类型
        String type = json.getString("type");
        // 国家
    	String countryName = json.getString("countryName");
        // 州/省
    	String stateName = json.getString("stateName");
        // 城市
    	String cityName = json.getString("cityName");
        // 邮编
    	String postcode = json.getString("postcode");
        // 街道1
    	String detail1 = json.getString("detail1");
        // 街道2
    	String detail2 = json.getString("detail2");
        // 门牌号
    	String doorplate = json.getString("doorplate");
    	
        // 以上字段变更后,需要重新审核进出口商信息
        boolean bl = !info.getType().equals(type) 
 || !info.getCountryName().equals(countryName)
                     || !info.getStateName().equals(stateName) || !info.getCityName().equals(cityName)
                     || !info.getPostcode().equals(postcode) || !info.getDetail1().equals(detail1)
                     || !info.getDetail2().equals(detail2) || !info.getDoorplate().equals(doorplate);
        return bl;
    }

    /**
     * 检查进出口商数据
     * 
     * @param command
     * @return EorIorInfo
     */
    private EorIorInfoDetailVo checkEorIorInfoData(Long id) {
        logger.info("检查进出口商数据");
        // 查询原进出口商信息
        EorIorInfoCommand queryCommand = new EorIorInfoCommand();
        queryCommand.setId(id);
        EorIorInfoDetailVo detailVo = eorIorInfoService.findEorIorInfoById(queryCommand);
        if (detailVo == null) {
            throw new ApiException(ErrorCode.ID_IS_NOT_EXISTS, id);
        }

        // 判断更新的数据所属用户是不是属于当前用户,不是则不允许修改
        if (!CommandContext.getContext().getUserId().equals(detailVo.getUserId())) {
            throw new ApiException(ErrorCode.RECORD_NOT_BELONG_CURRENT_USER, id);
        }
        return detailVo;
    }
}
